from ctypes import *
import time
import array
import amrconv
import struct

mydll = cdll.LoadLibrary('amrlib.dll')

def encode_init():
    return mydll.encode_init()

def encode_exit(state_p):
    return mydll.encode_exit(state_p)

def encode(state_p, mode, speech, serial, force_speech = 0):    
    l = mydll.encode(state_p, mode, byref(speech), byref(serial), force_speech)
    return l
    
def decode_init():
    return mydll.decode_init()

def decode_exit(state_p):
    return mydll.decode_exit(state_p)

def decode(state_p, amrData, data, param = 0):
    return mydll.decode(state_p, c_char_p(amrData), byref(data), param)

def wav2amr(wav, amr, mode = 5, cod = False):
    fwav = open(wav, 'rb')
    dwav = fwav.read()
    fwav.close()
    tempfn = amr if cod else 'temp.cod'
    famr = open(tempfn, 'wb')
    p = dwav.find('data') + 8
    speech = create_string_buffer(321)
    serial = create_string_buffer(32)
    state = encode_init()
    print 'wav len', len(dwav)
    c = 0    
    while p < len(dwav):
        #print 'p = ', p
        speech.raw = dwav[p:p+320]
        p += 320
        c += 1
        #print 'frame ', c
        l = encode(state, mode, speech, serial)
        #print 'l = ', l, ' data ', repr(serial.raw[:l])
        famr.write(serial.raw[:l])
    famr.close()
    encode_exit(state)
    None if cod else amrconv.if22amr('temp.cod', amr)

def amr2wav(amr, wav, cod = False):
    None if cod else amrconv.amr2if2(amr, 'temp.cod')
    tempfn = amr if cod else 'temp.cod'
    famr = open(tempfn, 'rb')
    damr = famr.read()    
    famr.close()
    
    p = 0
    speech = create_string_buffer(321)
    state = decode_init()    
    print 'amr len', len(damr)
    c = 0
    codes = {0:12,1:13,2:15,3:17,4:18,5:20,6:25,7:30, 8:5, 15:0}
    dwav = ''
    while p < len(damr):
        #print 'p = ', p
        mode = ord(damr[p]) & 0x000F
        p += 1
        p += codes[mode]
        c += 1
        #print 'frame ', c, ' mode ', mode
        decode(state, damr[p:p+codes[mode]], speech)
        dwav += speech.raw[:320]

    fwav = open(wav, 'wb')
    # write header according to http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
    fwav.write('RIFF')
    fwav.write(struct.pack('i', 40 + len(dwav)))
    fwav.write('WAVEfmt ')
    fwav.write(struct.pack('i', 16))
    fwav.write(struct.pack('h', 1)) # PCM
    fwav.write(struct.pack('h', 1)) # mono
    fwav.write(struct.pack('i', 8000)) # 8khz sr
    fwav.write(struct.pack('i', 2 * 8000 * 1))
    fwav.write(struct.pack('h', 2)) #
    fwav.write(struct.pack('h', 16)) #
    fwav.write('data')
    fwav.write(struct.pack('i', len(dwav)))
    fwav.write(dwav)
    fwav.close()
    decode_exit(state)    
    